//
// Created by Tunm-Air13 on 2024/3/15.
//

#include <jni.h>
#include <string>
#include <android/log.h>
#include <stdlib.h>
#include "log.h"
#include "jni_utils.h"
#include "simple_semantic.h"
#include "serror.h"

using namespace solex;

extern "C" {

JNIEXPORT jint JNICALL SIMPLE_SEMANTIC_API(core_SimpleSemanticCore_Initialization) (
        JNIEnv *env,
        jobject thiz,
        jobject simpleSemanticConfiguration) {

    // 获取SimpleSemanticConfiguration类
    jclass cls = env->GetObjectClass(simpleSemanticConfiguration);

    // 获取getFolderPath方法的ID
    jmethodID getFolderPathID = env->GetMethodID(cls, "getFolderPath", "()Ljava/lang/String;");

    // 调用getFolderPath方法
    jstring folderPath = (jstring)env->CallObjectMethod(simpleSemanticConfiguration, getFolderPathID);

    // 从jstring转换为C字符串（如果需要）
    const char *folderPathCStr = env->GetStringUTFChars(folderPath, NULL);
    if (folderPathCStr == NULL) {
        return SERR_JNI_PATH_ERROR;
    }
    // 获取getThreshold方法的ID
    jmethodID getThresholdID = env->GetMethodID(cls, "getThreshold", "()F");

    // 调用getThreshold方法
    jfloat threshold = env->CallFloatMethod(simpleSemanticConfiguration, getThresholdID);

    std::string pth = std::string(folderPathCStr);
    Configuration configuration;
    configuration.folderPath = pth;
    configuration.threshold = threshold;

    auto ret = InitSimpleSemantic(configuration);

    // 完成后释放C字符串
    env->ReleaseStringUTFChars(folderPath, folderPathCStr);
    env->DeleteLocalRef(folderPath);
    env->DeleteLocalRef(cls);  // 手动删除局部引用

    return ret;
}

JNIEXPORT jobject JNICALL SIMPLE_SEMANTIC_API(core_SimpleSemanticCore_AnalysisOfSentence) (
        JNIEnv *env,
        jobject thiz,
        jstring sentence) {
    // 获取字符串长度
    const jsize len = env->GetStringUTFLength(sentence);
    // 获取UTF-8编码的字符数组
    const char* strChars = env->GetStringUTFChars(sentence, (jboolean *)0);
    // 使用字符数组和长度创建std::string
    std::string sentenceStr(strChars, len);

    LOGD("inner: %s", sentenceStr.c_str());
    AnalysisResult analysisResult;
    auto ret = AnalysisOfSentence(sentenceStr, analysisResult);

    // 查找Java中的AnalysisResult类
    jclass analysisResultClass = env->FindClass("com/solexnlp/simplesemantic/data/AnalysisResult");
    if (analysisResultClass == NULL) {
        return NULL; // 类找不到异常应该在这里抛出
    }

    // 获取类的构造函数ID
    jmethodID constructor = env->GetMethodID(analysisResultClass, "<init>", "()V");
    jobject analysisResultObj = env->NewObject(analysisResultClass, constructor);

    // 设置execCode
    jfieldID fidExecCode = env->GetFieldID(analysisResultClass, "execCode", "I");
    env->SetIntField(analysisResultObj, fidExecCode, ret);

    // 如果函数调用成功，设置其他字段
    if (ret == SSUCCEED) {
        // 设置clsIndex
        jfieldID fidClsIndex = env->GetFieldID(analysisResultClass, "clsIndex", "I");
        env->SetIntField(analysisResultObj, fidClsIndex, analysisResult.clsIndex);

        // 设置probability
        jfieldID fidProbability = env->GetFieldID(analysisResultClass, "probability", "F");
        env->SetFloatField(analysisResultObj, fidProbability, analysisResult.probability);

        // 设置label
        jfieldID fidLabel = env->GetFieldID(analysisResultClass, "label", "Ljava/lang/String;");
        jstring labelStr = env->NewStringUTF(analysisResult.label.c_str());
        env->SetObjectField(analysisResultObj, fidLabel, labelStr);

        // 设置specialInt，如果specialInt不为空
        if (!analysisResult.specialInt.empty()) {
            jintArray specialIntArray = env->NewIntArray(analysisResult.specialInt.size());
            env->SetIntArrayRegion(specialIntArray, 0, analysisResult.specialInt.size(), reinterpret_cast<const jint *>(analysisResult.specialInt.data()));
            jfieldID fidSpecialInt = env->GetFieldID(analysisResultClass, "specialInt", "[I");
            env->SetObjectField(analysisResultObj, fidSpecialInt, specialIntArray);
            env->DeleteLocalRef(specialIntArray); // 删除局部引用
        }
    }

    // 释放JNI字符串资源
    env->ReleaseStringUTFChars(sentence, strChars);

    return analysisResultObj;

}

}